#include <iostream>

#include "MyPoint.h"

#include "Circle.h"
#include "Clock.h"
#include "ClockFriend.h"
#include "VirtualExtendsDemo.h"

//#include "constructor/LearnConstructor.h"

#include "ArrayList.h"
#include "Exception7_1.h"
#include "Exception10.h"

#include "iomanip"
#include<fstream>

#include "Person.h"
#include "DynamicArr.h"
#include "MethodTemplate.h"
#include "StackTemplate.h"

using namespace std;

//打印练习
void practicePrint();


//联合体学习
void learnUnion();

//是否闰年
void checkIsLeapYear();

//条件编译注释 如果 if满足就会把if的内容包括进去
#if 0
asd
#endif

//x的n 次方
double power(double x, int n);

//递归 求 1+到n的数值
void recursion1(int n);

//结构体
void learStruct();

//静态变量
void learnStatic();

//enum
void learnEnum();

//求π
double arctan(double x);

//随机数 投色子
void rollDiceExercise();

//内联函数练习
inline double CalArea(double radius);

//交换两个数
void swap(int &a, int &b);

void temperature(int t) {
    try {
        if (t == 100) throw "It's at the boiling point.";
        else if (t == 0) throw "It reached the freezing point";
        else cout << "the temperature is OK..." << endl;
    }
    catch (int x) { cout << "temperature=" << x << endl; }
    catch (char const *s) { cout << s << endl; }
}

void handler(int n) throw(int, char, double) {
    if (n == 1) throw n;
    if (n == 2) throw 'x';
    if (n == 3) throw 1.1;
}

//内部再次throw异常的时候，函数不要带throw()
void Errhandler(int n) {
    try {
        if (n == 1) throw n;
        cout << "all is ok..." << endl;
    }
    catch (int n) {
        cout << "catch an int exception inside..." << n << endl;
        throw n;                                     //再次抛出本catch捕获的异常
    }
}

int main() {

    iInvoke * dynamicArr
//            = new DynamicArr();
//            = new MethodTemplate();
            = new StackTemplate();


    dynamicArr->invoke();

//    cout<<"Before handler..."<<endl;
//    try{
//        handler(1);
//    }
//    catch(int i){ cout<<"catch an integer..."<<endl;}
//    catch(char c){cout<<"catch an char..."<<endl;}
//    catch(double d){cout<<"catch an double..."<<endl;}

//    try{
//        Errhandler(1);
//    }
//    catch(int x){ cout<<"catch int an exception in main..."<<x<<endl; }
//    cout<<"....End..."<<endl;

//    B *bPtr;
//    try {
//        B b(2);
//        bPtr = &b;
//        system("pause");
//    }
//    catch (int e) {
//        cout << "catch an exception when allocated pb[" << e << "]" << endl;
//    }

//    Exception10Main();


//    practicePrint();

//    learnUnion();

//    checkIsLeapYear();

//5的2次方
//    cout << power(5, 2) << endl;


//递归1 从1加到n
//    recursion1(100);

//
//    learStruct();


//    learnStatic();

//    learnEnum();

//求π
//    double a = 16.0 * arctan(1.0 / 5.0);
//    double b = 4.0 * arctan(1.0 / 239.0);
//    double pi = a - b;
//    cout << pi << endl;


//    rollDiceExercise();

//    cout << CalArea(20) << endl;

//交换
//    int a = 1;
//    int b = 2;
//    cout << &a << ":" << a << "\n"
//         << &b << ":" << b << endl;
//    swap(a, b);
//
//    cout << &a << ":" << a << "\n"
//         << &b << ":" << b << endl;

//1
//    MyPoint A(4, 5);
//    cout << "Point A," << A.GetX() << "," << A.GetY() << endl;
//    A.GetC();
//
//    MyPoint B(A);
//    cout << "Point B," << B.GetX() << "," << B.GetY() << endl;
//    B.GetC();

//综合练习
//    float radius;
//    float FenceCost, ConcreteCost;
//    float ConcretePrice=20;
//    float FencePrice=35;
//
//    //提示输入半径
//    cout << "Enter the radius of the pool:";
//    cin >> radius;
//
//    Circle Pool(radius);
//    Circle PoolRim(radius + 3);
//    //计算栅栏造价并输出
//    FenceCost = PoolRim.Circumference() *  FencePrice;
//
//    cout << "cost=" << FenceCost << endl;
//
//    //计算过道
//    ConcreteCost = (PoolRim.Area() - Pool.Area()) * ConcretePrice;
//    cout << "cost=" << ConcreteCost << endl;

//    Clock time(23,59,59);
//    ++time;
//    time.showTime();
//    time.operator()(1,1,1);
//    time.showTime();
//    time(2,2,3);
//    time.showTime();
//
//    ClockFriend cf(time);
//    cf.resetClock();
//    time.showTime();


//    LearnConstructor c;

//    VD vd;
//    vd.printA();
//    vd.VB::printA();

//    int iarr[] = {1, 2, 3, 4, 5, 6, 7};
//    ArrayList<int> intList;
//    for (int i = 0; i < getArrayLen(iarr); i++) {
//        intList.add(iarr[i]);
//        intList.print();
//    }



//
//    temperature(0);						//L1
//    temperature(10);						//L2
//    temperature(100);						//L3

//    char a,b,c,d;
//    cin.get(a);
//    cin.get(b);
//    c = cin.get();
//    d = cin.get();
//    cout<<int(a)<<','<<int(b)<<','<<int(c)<<','<<int(d)<<endl;

//1.输入串长<size，输入串长>arraylength，会自动扩张arrayname大小，使能保存所有数据
//     char a[10];
//     cin.get(a,20);//超过 20 的也不会保存的 只会保持19个 最后一个是\0
//     cout<<a<<endl;

    //2.输入串长<size，输入串长<arraylength，把串全部输入，后面补‘\0’
//    char b[10];
//    cin.get(b, 20);
//    cout << b << endl;//12345，此时数组内数据为‘12345'\0’

    //3.输入串长>size，先截取size个字符，若还是大于arraylength，则输入前arraylength-1个字符，最后补充‘\0’
//     char c[5];
//     cin.get(c,10);
//     cout<<c<<endl;
//     cout<<sizeof(c)<<endl;

//4.输入串长>size，先截取size个字符，若小于arraylength，则把截取串放入数组中，最后补充‘\0’
//     char d[10];
//     cin.get(d,5);
//     cout<<d<<endl;
//     cout<<sizeof(d)<<endl;

//get()三个参数
    /*
        用法：cin.get(arrayname,size,s) ?把数据输入到arrayname字符数组中，
        当到达长度size时结束或者遇到字符s时结束
        注释：a必须是字符数组，即char a[]l类型，不可为string类型；
        size为最大的输入长度；s为控制，遇到s则当前输入结束缓存区里的s将被舍弃

        上述限制它是在按下回车键后触发的
    */
//    int i;
//    char e[10];
//    cin.get(e,8,',');
//    cout<<e;


//    char e[10];
//    char f;
//    cin.get(e,10,',');
//    cin.get(f);
//    cout<<e<<endl<<f;//输入：12345,[enter] 输出：12345【换行】，说明：cin,get不会删除缓冲区的，*/
//    char e1[10];
//    char f1;
//    cin.getline(e1,10,',');
//    cin.get(f1);
//    cout<<e1<<endl<<f1;//输入：asd,wqe 输出：asd【换行】w


//输入 12,34,56,78,90,
//输出 :
//12
//34
//56
//78
//90
//    char stu[5][10];
//    int i;
//    for (i = 0; i < 5; i++)
//        cin.getline(stu[i], 10, ',');
//    for (i = 0; i < 5; i++)
//        cout << stu[i] << endl;

//    char c;
//    char a[50]="this is a string...";
//    cout<<"use get() input char:";
//    while((c=cin.get())!='\n'){
//        cout.put(c);
//        cout.put('\n');
//        cout.put('t').put('h').put('i').put('s').put('\n');
//        cout.write(a,12).put('\n');
//        cout<<"look"<<"\t here!"<<endl;
//    }

//    char c[30] = "this is string";
//    double d = -1234.8976;
//
//    //setW 可以理解为 设置宽度一样 ,然后后面设置 左边/右边 空白处填充*
//    cout << setw(30) << left << setfill('*') << c << "----L1" << endl;//this is string****************----L1
//    cout << setw(30) << right << setfill('*') << c << "----L2" << endl;//****************this is string----L2
//    //showbase显示数值的基数前缀
//    cout << dec << showbase << showpoint << setw(30) << d << "----L3" << "\n";//**********************-1234.90----L3
//    //showpoint显示小数点
//    cout << setw(30) << showpoint << setprecision(10) << d << "----L4" << "\n";//******************-1234.897600----L4
//    //setbase(8)设置八进制
//    cout << setw(30) << setbase(16) << 100 << "----L5" << "\n";//**************************0x64----L5



    //文件流
//    fstream ioFile;
//    ioFile.open("./a.dat",ios::out);
//    ioFile<<"张三"<<"  "<<76<<" "<<98<<" "<<67<<endl;	//L3
//    ioFile<<"李四"<<"  "<<89<<" "<<70<<" "<<60<<endl;
//    ioFile<<"王十"<<"  "<<91<<" "<<88<<" "<<77<<endl;
//    ioFile<<"黄二"<<"  "<<62<<" "<<81<<" "<<75<<endl;
//    ioFile<<"刘六"<<"  "<<90<<" "<<78<<" "<<67<<endl;
//    ioFile.close();
//    ioFile.open("./a.dat",ios::in|ios::binary);
//    char name[10];
//    int chinese,math,computer;
//    cout<<"姓名\t"<<"英语\t"<<"数学\t"<<"计算机\t"<<"总分"<<endl;
//    ioFile>>name;
//    while(!ioFile.eof())	{
//        ioFile>>chinese>>math>>computer;
//        cout<<name<<"\t"<<chinese<<"\t"<<math<<"\t"<<computer<<"\t"<<chinese+math+computer<<endl;
//        ioFile>>name;
//    }
//    ioFile.close();

    //文件 io 方式2
//    char ch;
//    ofstream out("./test.dat", ios::out | ios::binary);        //L1
//    for (int i = 0; i < 90; i++) {
//        if (i > 0 && (i % 30) == 0)
//            out.put('\n');
//        out.put(i);
//        out.put(' ');
//
//    }
//    out.close();
//
//    ifstream in("./test.dat", ios::in | ios::binary);
//    while (in.get(ch))
//        cout << ch;
//    in.close();

//    vector<Person> v;
//    vector<Person>::iterator pos;//声明一个迭代器，来访问vector容器，作用：遍历或者指向vector容器的元素
//    char ch;
//    ofstream out("d:/person.dat", ios::out | ios::app | ios::binary);
//    char Name[20], ID[18], Addr[20];
//    int Age;
//    cout << "------输入个人档案------" << endl << endl;
//    do {
//        cout << "姓名： ";
//        cin >> Name;
//        cout << "身份证号： ";
//        cin >> ID;
//        cout << "年龄： ";
//        cin >> Age;
//        cout << "地址： ";
//        cin >> Addr;
//        Person per(Name, ID, Age, Addr);
//        out.write((char *) &per, sizeof(per));
//        cout << "Enter another Person(y/n)?";
//        cin >> ch;
//    } while (ch == 'y');
//    out.close();
//    ifstream in("d:/person.dat", ios::in | ios::binary);    //L9
//    Person s;
//    in.read((char *) &s, sizeof(s));
//    while (!in.eof()) {
//        v.push_back(s);
//        in.read((char *) &s, sizeof(s));
//    }
//    cout << "\n---------从文件中读出的数据--------" << endl << endl;//L15
//    pos = v.begin();
//    for (pos = v.begin(); pos != v.end(); pos++)
//        (*pos).display();

    return 0;
}


void practicePrint() {

    int i, j, k, f;
    for (i = 1; i < 4; i++) {
        for (j = 1; j <= 30; j++) {
            cout << " ";
        }
        for (k = 1; k <= 8 - 2 * i; k++)
            cout << " ";

        for (f = 1; f <= 2 * i; f++)
            cout << '*';

        cout << endl;

    }

    for (i = 1; i <= 3; i++) {
        for (j = 1; j <= 30; j++)
            cout << " ";
        for (f = 1; f <= 7 - 2 * i; f++)
            cout << '*';
        cout << endl;
    }


}


union myunion {
    struct {
        int x;
        int y;
        int z;
    } u;

    int k;
} a;

void learnUnion() {

    //u 里面是不共享
    // 但是 u 和 k是共享的 所以 k 占用了u的一部分 也就是 x的位置
    a.u.x = 4;
    a.u.y = 5;
    a.u.z = 6;
    a.k = 0;
    //结果是  0560   x的内存和k是同一个
    cout << a.u.x << a.u.y << a.u.z << a.k << endl;

}

void checkIsLeapYear() {
    //是4的倍数同时不是100的倍数 但可以是400的倍数
    int year = 2021;

    bool isLeapYear = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;

    if (isLeapYear) {
        cout << "闰年" << endl;
    } else {
        cout << "非闰年" << endl;
    }


}

double power(double x, int n) {
    double value = 1.0;
    for (int i = 0; i < n; i++) {
        value *= x;
    }
    return value;
}


int caculate1FromN(int n) {
    if (n == 1) {
        return 1;
    } else {
        return n + caculate1FromN(n - 1);
    }
}

void recursion1(int n) {

    cout << "从1加到" << n << "结果是" << caculate1FromN(n) << endl;


}


struct student {
    int num;
    char name[20];
    char gender;
};

void learStruct() {

    student mouse = {
            10,
            "鼠标",
            'M',
    };

    cout << mouse.num
         << ","
         << sizeof(mouse.num) //result is 4
         << ","
         << sizeof(mouse.name) //result is 20
         << ","
         << sizeof(mouse.gender) //result is 1
         << ","
         << sizeof(mouse)  //结果是  28  结果看起来不对 4+20+1 = 25
         // 因为内存需要对齐 所以整体所占的内存是大于等于总占空间的 并且是4的倍数 (根据系统决定)
         << endl;


}

//全局变量 具有静态生存期
int staticI = 1;

void other(void) {

    // a,b为静态局部变量，具有全局寿命，局部可见。
    static int a = 2;
    static int b;
    // C为局部变量，具有动态生存期 每次进入函数时都初始化。
    int c = 10;
    a = a + 2;
    staticI = staticI + 32;
    c = c + 5;
    cout << "====other====\n"
         << " i:" << staticI
         << " a:" << a
         << " b:" << b
         << " c:" << c
         << endl;

    b = a;

}

void learnStatic() {

    static int a;
    int b = -10;
    int c = 0;

    other();
    cout << "====Main====\n"
         << " a:" << a
         << " b:" << b
         << " c:" << c
         << endl;

    c = c + 8;

    cout << "====Main====\n"
         << " a:" << a
         << " b:" << b
         << " c:" << c
         << endl;

    staticI = staticI + 10;

    other();

}


enum weekday {
    s, m, t, w, thu, f, s1
};

void learnEnum() {

    enum weekday wek = s;
    // weekday wek=s;
    for (int i = wek; i != f; i++) {
        cout << i << endl;
        cout << wek + s << endl;
        cout << "-------哈哈-------" << endl;
    }

}

/**
 *
 * 这个 计算的公式 算法还没懂
 * 后面研究一下求π的公式和算法
 * @param x
 * @return
 */
double arctan(double x) {

    double head = x;
    int tail = 1;
    double art = 0;
    while (double(head / tail) > 1e-15) {

        art = (tail % 4 == 1) ? (art + head / tail) : (art - head / tail);

        head *= x * x;
        tail += 2;
        cout << "===========================" << endl;
        cout << tail << endl;
        cout << "===============================" << endl;

    }

    return art;
}


int rollADice() {
    return rand() % 6 + 1;
}

int rollDices(int diceCount) {
    int dim = 0;
    if (diceCount <= 0) {

    }
    for (int i = 0; i < diceCount; i++) {
        dim += rollADice();
    }
    return dim;
}

void rollDiceExercise() {
    //随机数种子 要不然每次都一样了
    srand(1998);
    cout << rollDices(2) << endl;

}

inline double CalArea(double radius) {
    return 3.14 * radius * radius;
}

void swap(int &a, int &b) {
    int t;
    t = a;
    a = b;
    b = t;
}